// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 * Author: Huawei OS Kernel Lab
 * Create: Thu Aug 15 16:14:23 2023
 */

#include <liblinux/pal.h>

#include <linux/types.h>
#include <linux/export.h>
#include <linux/dma-direction.h>

void __flush_icache_range(unsigned long start, unsigned long end)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_ICACHE_FLUSH_RANGE, start, end);
}

void v7_coherent_kern_range(unsigned long start, unsigned long end)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_ICACHE_FLUSH_RANGE, start, end);
}

void v7_flush_kern_dcache_area(void *addr, size_t len)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_FLUSH_RANGE,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}
EXPORT_SYMBOL(v7_flush_kern_dcache_area);

void __flush_dcache_area(void *addr, size_t len)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_FLUSH_RANGE,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}
#ifdef CONFIG_ARM64
EXPORT_SYMBOL(__flush_dcache_area);
#endif

void __clean_dcache_area_pou(void *addr, size_t len)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_CLEAN_RANGE,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}

void __dma_map_area(const void *addr, size_t len, int dir)
{
	unsigned int cmd;

	if (dir == DMA_FROM_DEVICE)
		cmd = LIBLINUX_PAL_DCACHE_INVAL_RANGE;
	else
		cmd = LIBLINUX_PAL_DCACHE_CLEAN_RANGE;

	liblinux_pal_flush_cache_range(cmd,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}

void __dma_unmap_area(const void *addr, size_t len, int dir)
{
	if (dir == DMA_TO_DEVICE)
		return;

	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_INVAL_RANGE,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}

void __dma_flush_area(const void *start, size_t size)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_FLUSH_RANGE,
				       (unsigned long)(uintptr_t)start,
				       (unsigned long)((uintptr_t)start + size));
}

#ifdef CONFIG_ARM64
void flush_cache_all(void)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_CACHE_FLUSH_ALL, 0, (unsigned long)-1);
}
EXPORT_SYMBOL(flush_cache_all);

void __inval_dcache_area(void *addr, size_t len)
{
	liblinux_pal_flush_cache_range(LIBLINUX_PAL_DCACHE_INVAL_RANGE,
				       (unsigned long)addr,
				       (unsigned long)addr + len);
}
EXPORT_SYMBOL(__inval_dcache_area);
#endif
